/*
 * Copyright (c) 1989 - 1999 Microsoft Corporation
 */

#include "precomp.h"
#pragma hdrstop

#include "mrxglobs.h"
#include "host_access.h"

NTSTATUS
HwFsRead(
    IN PRX_CONTEXT RxContext)
{
    NTSTATUS Status = STATUS_SUCCESS;

    PHWFS_DEVICE_EXTENSION   pDevExt = HWFS_GET_DEVICE_EXTENSION(RxContext);

    __notnull PMRX_FCB Fcb = RxContext->pFcb;
    PHWFS_FCB_EXTENSION pFcbExt = HWFS_GET_FCB_EXTENSION(Fcb);

    PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
    HWFS_SRVOPEN_EXTENSION* pSrvOpenExt = SrvOpen->Context;

    PMRX_NET_ROOT pNetRoot = Fcb->pNetRoot;
    PHWFS_NETROOT_EXTENSION pNetRootExtension = pNetRoot->Context;

    PLOWIO_CONTEXT LowIoContext  = &RxContext->LowIoContext;
    PMDL pBufferMdl = LowIoContext->ParamsFor.ReadWrite.Buffer;
    ULONG ByteCount = LowIoContext->ParamsFor.ReadWrite.ByteCount;
    RXVBO ByteOffset = LowIoContext->ParamsFor.ReadWrite.ByteOffset;
    LONGLONG FileSize = 0;
    BOOLEAN SynchronousIo = !BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION);

    RxContext->InformationToReturn = 0;

    RxTraceEnter("HwFsRead");

    RxGetFileSizeWithLock((PFCB)Fcb, &FileSize);

    //
    //  NB: This should be done by the wrapper ! It does this
    //  only if READCACHEING is enabled on the FCB !!
    //
    if (!FlagOn(Fcb->FcbState, FCB_STATE_READCACHING_ENABLED)) {
        //
        // If the read starts beyond End of File, return EOF.
        //
        if (ByteOffset >= FileSize) {
            HWFS_DBG_PRINT(DBG_TRACE, DBG_FREAD,
                ("Read after End of File: 0x%I64x:0x%I64x\n", ByteOffset, FileSize));
            Status = STATUS_END_OF_FILE;
            goto Exit;
        }

        //
        //  If the read extends beyond EOF, truncate the read
        //
        if (ByteCount > FileSize - ByteOffset) {
            ByteCount = (ULONG)(FileSize - ByteOffset);
        }
    }

    HWFS_DBG_PRINT(DBG_TRACE, DBG_FREAD,
        ("ByteCount is 0x%x ByteOffset is 0x%x; FileSize 0x%x\n", ByteCount, ByteOffset, FileSize));

    Status = HostReadFile(pDevExt, &pSrvOpenExt->HwfsFile,
        ByteOffset, pBufferMdl, ByteCount, &RxContext->InformationToReturn);

Exit:

    RxTraceLeave(Status);
    return(Status);
}
